package com.blood.core.config.interceptor;

import cn.hutool.jwt.JWT;
import com.blood.core.annotation.JwtIgnore;
import com.blood.core.config.AudienceConfig;
import com.blood.core.constant.RedisKey;
import com.blood.core.enums.AuthorityTypeEnum;
import com.blood.core.enums.StatusEnum;
import com.blood.core.po.SysUserInfo;
import com.blood.core.resp.GlobalResultStatus;
import com.blood.core.util.ObjectAssertUtil;
import com.blood.core.util.http.RequestTheadUtils;
import com.blood.core.util.token.JwtTokenUtil;
import com.blood.redis.config.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author daoren
 * @description
 */
@Slf4j
public class AuthenticationInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private AudienceConfig audienceConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) {
        final String platform = request.getHeader(JwtTokenUtil.PLATFORM);
        SysUserInfo userInfo = new SysUserInfo();
        userInfo.setPlatform(platform);
        String path = request.getRequestURI();
        userInfo.setUrl(path);
        RequestTheadUtils.setInfo(userInfo);
        // 忽略带JwtIgnore注解的请求
        if (object instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) object;
            JwtIgnore jwtIgnore = handlerMethod.getMethodAnnotation(JwtIgnore.class);
            if (null != jwtIgnore) {
                return true;
            }
        }
        // 获取请求头信息authorization信息
        final String token = request.getHeader(JwtTokenUtil.AUTH_HEADER_KEY);
        ObjectAssertUtil.isBoolean(StringUtils.isBlank(token)
                        || !token.startsWith(JwtTokenUtil.TOKEN_PREFIX)
                , GlobalResultStatus.NOT_LOGIN);
        //获取token
        final String token1 = token.substring(7);

        // 验证token是否有效--无效已做异常抛出，由全局异常处理后返回对应信息
        JWT jwt = JwtTokenUtil.parseJWT(token1, audienceConfig.getBase64Secret());
        String userId = (String) jwt.getPayload("userId");
        userInfo.setUserId(userId);
        Object userObject = redisUtil.get(RedisKey.USER_INFO.concat(userId));
        ObjectAssertUtil.objectIsNull(userObject, GlobalResultStatus.NOT_LOGIN);
        SysUserInfo sysUserInfo = (SysUserInfo) userObject;
        ObjectAssertUtil.isBoolean(!sysUserInfo.getStatus().equals(StatusEnum.ENABLE.getValue()), "账号已冻结!");
        userInfo.setOrgId(sysUserInfo.getOrgId());
        userInfo.setRole(sysUserInfo.getRole());
        userInfo.setHospitalId(sysUserInfo.getHospitalId());
        userInfo.setDepartId(sysUserInfo.getDepartId());
        Object loginRole = redisUtil.get(RedisKey.ROLE_AUTH.concat(sysUserInfo.getRole()).concat("-") + AuthorityTypeEnum.LOGIN.getValue());
        ObjectAssertUtil.isBoolean(null != loginRole && loginRole.equals(StatusEnum.DIS_ENABLE.getValue()), "该角色禁止登录系统！");
        return true;
    }
}
